﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using Scheduling.Models;
using System.IO;

namespace MultipleBooking
{
    class GeneratorWindow : Form
    {
        ListBox roomList;
        ListBox userList;
        ListBox requestList;
        ListBox resultList;
        List<ListBox> listBoxes;
        Button generateButton;
        MainMenu mainMenu;
        MenuItem generateRandom;
        MenuItem addTeacher;
        MenuItem addRoom;
        MenuItem addRequest;
        MenuItem clearAll;
        PictureBox bookingGraph;

        List<Booking> bookingList;
        public GeneratorWindow()
        {
            userList = new ListBox(); roomList = new ListBox();
            requestList = new ListBox(); resultList = new ListBox();

            Program.UserList = new List<User>();
            Program.Requests = new List<BookingRequest>();
            listBoxes = new List<ListBox>() { roomList, userList, requestList, resultList };
            foreach (var lb in listBoxes)
                this.Controls.Add(lb);

            generateButton = new Button();
            generateButton.Text = "Generate";
            generateButton.Click += new EventHandler(generateButton_Click);

            mainMenu = new MainMenu();
            generateRandom = new MenuItem("Generate");
            addTeacher = new MenuItem("Add Teacher");
            addRoom = new MenuItem("Add Room");
            addRequest = new MenuItem("Add Request");
            clearAll = new MenuItem("Clear All");
            generateRandom.Click += new EventHandler(generateRandom_Click);
            mainMenu.MenuItems.Add(generateRandom);
            mainMenu.MenuItems.Add(addRequest);
            mainMenu.MenuItems.Add(addRoom);
            mainMenu.MenuItems.Add(addTeacher);
            mainMenu.MenuItems.Add(clearAll);
            addTeacher.Click += new EventHandler(addTeacher_Click);
            addRoom.Click += new EventHandler(addRoom_Click);
            addRequest.Click += new EventHandler(addRequest_Click);
            clearAll.Click += new EventHandler(clearAll_Click);

            bookingGraph = new PictureBox() { SizeMode = PictureBoxSizeMode.StretchImage };
            this.Controls.Add(bookingGraph);

            this.Menu = mainMenu;

            this.Controls.Add(generateButton);
            clearAll_Click(null, null);
        }

        void clearAll_Click(object sender, EventArgs e)
        {
            Program.MultiBooker.BookingList.Clear();
            Program.MultiBooker.NewBookings.Clear();
            Program.MultiBooker.RoomList.Clear();
            Program.Requests.Clear();
            Program.UserList.Clear();
            UpdateLists();
        }

        void addRequest_Click(object sender, EventArgs e)
        {
            List<string> o;
            if (Dialogs.InputBox("Request", out o, "Teacher ID", "Room Pattern", "Lecture Count", "Lecture Length", 
                "Priority", "Required Capacity", "Time") == System.Windows.Forms.DialogResult.OK)
            {
                Program.Requests.Add(new BookingRequest()
                {
                    ID = Program.Requests.Count == 0 ? 0 : Program.Requests.OrderBy(u => u.ID).Last().ID + 1,
                    Booker = Program.UserList.Where(u => u.ID == o[0]).First(),
                    RoomPattern = o[1],
                    LectureCount = int.Parse(o[2]),
                    LectureLength = int.Parse(o[3]),
                    Priority = (Priority)Enum.Parse(typeof(Priority), o[4]),
                    RequiredCapacity = int.Parse(o[5]),
                    StartPeriod = 1,
                    Time = int.Parse(o[6]),
                    Year = 2011,
                    CourseInstance = new CourseInstance() { ID = 0, Course = new Course() { ID = "0" } },
                    AllowedDays = new Dictionary<DayOfWeek, DayType>()
                    {
                        { DayOfWeek.Monday, DayType.Every },
                        { DayOfWeek.Tuesday, DayType.Every },
                        { DayOfWeek.Wednesday, DayType.Odd }
                    }
                });
                UpdateLists();
            }
        }

        void addRoom_Click(object sender, EventArgs e)
        {
            List<string> o;
            if (Dialogs.InputBox("Room", out o, "Room ID", "Room Capacity") == System.Windows.Forms.DialogResult.OK)
            {
                Program.MultiBooker.RoomList.Add(new Room() { ID = o[0], Capacity = int.Parse(o[1]) });
                UpdateLists();
            } 

        }

        void addTeacher_Click(object sender, EventArgs e)
        {
            List<string> o;
            if (Dialogs.InputBox("Teacher", out o, "Teacher ID") == System.Windows.Forms.DialogResult.OK)
            {
                Program.UserList.Add(new User() { ID = o[0] });
                UpdateLists();
            } 
        }

        void generateButton_Click(object sender, EventArgs e)
        {
            Program.MultiBooker.BookingList.Clear();
            if (!Program.MultiBooker.GenerateBookings(Program.Requests, 2011, 1))
            {   
                MessageBox.Show("Could not fit all booking into schedule. ", "MultiBooking", MessageBoxButtons.OK, MessageBoxIcon.Warning);
            }
            Program.MultiBooker.NewBookings = Program.MultiBooker.BookingList.OrderBy(b => b.StartDate).ToList();
            var bmp = GraphDrawer.DrawGraph(Program.MultiBooker.NewBookings, Program.MultiBooker.RoomList);
            bookingGraph.Image = bmp;
            bmp.Save("graph.jpg");
            File.WriteAllText("tran.txt", Program.MultiBooker.GenerateTransaction());
            System.Diagnostics.Process.Start("tran.txt");
            UpdateLists();
        }

        void generateRandom_Click(object sender, EventArgs e)
        {
            CountWindow countWindow = new CountWindow();
            countWindow.ShowDialog();

            Program.GenerateRandomStuff(countWindow.UserCount, countWindow.RoomCount, countWindow.RequestCount, countWindow.SeedCount);
            UpdateLists();
        }

        private void UpdateLists()
        {
            int i = 0;
            foreach (var lb in listBoxes)
                lb.Items.Clear();
            foreach (var u in Program.UserList)
                userList.Items.Add(u.ToString());
            foreach (var r in Program.MultiBooker.RoomList)
                roomList.Items.Add(r.ToString());
            foreach (var r in Program.Requests)
                requestList.Items.Add(r.ToString());
            foreach (var b in Program.MultiBooker.NewBookings)
            {
                i++;
                resultList.Items.Add(i.ToString().PadLeft(4) + ": " + b.ToString());
            }
        }
        protected override void OnLoad(EventArgs e)
        {
            this.Show();
            Redraw();
            this.TopMost = true;
            this.BringToFront();
            this.TopMost = false;
            
        }
        protected override void OnSizeChanged(EventArgs e)
        {
            base.OnSizeChanged(e);
            Redraw();
        }
        private void Redraw()
        {
            int bottomPictureHeight = 48;
            int rightBoxHeight = this.Height - 48 - 24 - bottomPictureHeight;
            int splitBoxWidth = this.Width / 2 - 24;
            int leftBoxHeight = rightBoxHeight / 3;

            foreach (var lb in listBoxes)
            {
                lb.Font = new Font("Courier New", 10.0f);
            }

            for (int i = 0; i < 3; i++)
            {
                var lb = listBoxes[i];
                lb.Height = leftBoxHeight;
                lb.Top = i * (leftBoxHeight + 10);
                lb.Width = splitBoxWidth;
            }

            resultList.Top = 0;
            resultList.Left = splitBoxWidth + 8;
            resultList.Width = splitBoxWidth;
            resultList.Height = rightBoxHeight;

            generateButton.Left = splitBoxWidth + 8;
            generateButton.Top = rightBoxHeight - 4;
            generateButton.Width = splitBoxWidth;

            bookingGraph.Top = this.Height - bottomPictureHeight - 48;
            bookingGraph.Left = 8;
            bookingGraph.Width = this.Width - 16;
        }
    }


}
